import { EnumBjlResult } from "../enums/EnumBjlResult";
import { ExcutePlanOption, RecmInfo, RoundInfo, SummaryInfo } from "./ExecutePlan";
import { IPlan } from "./IExecutePlan";
import { IMoneyStrategy } from "./IMoneyStrategy";
import { IRecmStrategy } from "./IRecmStrategy";

export interface PlanWithSubPlanOption {
    subPlan: IPlan[];
}

/**
 * 计划
 */
export class ExcutePlanWithSubPlan implements IPlan {
    recmInfo: RecmInfo = new RecmInfo();
    userRecmInfo: RecmInfo = new RecmInfo();
    multiple: number;
    waterRate: number;
    fuliRate: number;
    baseMoney: number;
    strategyName: string = '';
    relationPindex: number[] | null = null;
    subPlan: IPlan[] = [];
    running: boolean = true;
    zSum: number = 0;
    xSum: number = 0;
    resetMoney?: number = 0;
    bflag: boolean = false;
    originMultiple: number = 0;
    constructor() {
        this.resetStrategy();
        this.multiple = 1;
        this.waterRate = 0.05;
        this.fuliRate = 0.01;
        this.baseMoney = 100;
    }
    debugCompoenent: string = "";
    /**
     * 计划id
     */
    id: string = "";
    /**
     * 计划名称
     */
    planName: string = "";
    /**
     * 方向推荐策略
     */
    recmStrategy: IRecmStrategy[] = [];
    /**
     * 金额推荐策略
     */
    moneyStrategy: IMoneyStrategy[] = [];
    resetRecm(): void {
        this.recmInfo.recmV = EnumBjlResult.U;
        this.userRecmInfo.recmV = EnumBjlResult.U;
    }
    resetStrategy(): void {
        this.recmInfo = new RecmInfo();
        this.userRecmInfo = new RecmInfo();
    }
    copyValue(valueObj: any): void {
        let plan = valueObj as ExcutePlanWithSubPlan;
        if (plan) {
            this.id = plan.id;
            this.xSum = plan.xSum;
            this.zSum = plan.zSum;
            this.recmInfo.copyValue(plan.recmInfo);
            this.userRecmInfo.copyValue(plan.userRecmInfo);
            for (let i = 0; i < this.recmStrategy.length; i++) {
                this.recmStrategy[i].copyValue(plan.recmStrategy[i]);
            }

            for (let i = 0; i < this.moneyStrategy.length; i++) {
                this.moneyStrategy[i].copyValue(plan.moneyStrategy[i]);
            }
            for (let i = 0; i < this.subPlan.length; i++) {
                this.subPlan[i].copyValue(plan.subPlan[i]);
            }

            if (this.resetSummaryInfo && plan.resetSummaryInfo) {
                this.resetSummaryInfo.copyValue(plan.resetSummaryInfo);
            }
            else if (this.resetSummaryInfo == null) {
                this.resetSummaryInfo = plan.resetSummaryInfo;
            }
            else {
                this.resetSummaryInfo = null;
            }


        }
    }
    /**
     * 
     * @param roundInfo 
     * @param recmInfo 
     * @param multiple 
     */
    setResult(roundInfo: RoundInfo, recmInfo: RecmInfo, multiple: number, waterRate: number, fuliRate: number): void {
        let recmMoney = this.recmInfo.recmMoney;
        if (this.multiple > 0) {
            recmMoney = recmMoney * this.multiple;
        }
        this.recmInfo.summaryInfo.updateSummaryInfo(roundInfo.currentResult, this.recmInfo.recmV, recmMoney, this.waterRate, this.fuliRate);
        this.recmInfo.roundSummaryInfo.updateSummaryInfo(roundInfo.currentResult, this.recmInfo.recmV, recmMoney, this.waterRate, this.fuliRate);

        this.userRecmInfo.summaryInfo.updateSummaryInfo(roundInfo.currentResult, this.userRecmInfo.recmV, recmMoney, this.waterRate, this.fuliRate);
        this.userRecmInfo.roundSummaryInfo.updateSummaryInfo(roundInfo.currentResult, this.userRecmInfo.recmV, recmMoney, this.waterRate, this.fuliRate);


        this.subPlan.forEach(pl => {
            pl.setResult(roundInfo, pl.recmInfo, multiple, waterRate, fuliRate);
        });
    }
    /**
     * 计算本地投注方向
     * @param roundInfo 信息
     */
    toResult(roundInfo: RoundInfo): EnumBjlResult {
        let zc = 0;
        let xc = 0;
        this.subPlan.forEach(pl => {
            let rv = pl.toResult(roundInfo);
            pl.userRecmInfo.recmV = rv;
            if (rv == EnumBjlResult.Z) {
                zc++;
            }
            else if (rv == EnumBjlResult.X) {
                xc++;
            }
        });
        if (zc > xc) return EnumBjlResult.Z;
        else if (xc > zc) return EnumBjlResult.X;
        else return EnumBjlResult.U;
    }
    /**
     * 
     * @param roundInfo 
     * @param recmInfo 
     * @param userRecm 
     * @param baseMoney 
     * @returns 
     */
    toMoney(roundInfo: RoundInfo, recmInfo: RecmInfo, userRecm: RecmInfo, baseMoney: number): [EnumBjlResult, number] {
        let zm = 0;
        let xm = 0;
        let recmMoney = 0;
        let recmV = EnumBjlResult.U;

        this.subPlan.forEach(pl => {
            if (pl.running) {
                let userRecmV = pl.toResult(roundInfo);
                var round = Object.assign({}, roundInfo, { userRecm: userRecmV })
                let [rv, rm] = pl.toMoney(round, pl.recmInfo, userRecm, baseMoney);
                pl.recmInfo.recmV = rv;
                let rmMoney = rm * pl.multiple;
                pl.recmInfo.recmMoney = rmMoney;//rm * pl.multiple;
                if (rv == EnumBjlResult.Z) {
                    zm += rmMoney;
                }
                else if (rv == EnumBjlResult.X) {
                    xm += rmMoney;
                }
            }
            else {
                pl.recmInfo.recmV = EnumBjlResult.U;
            }
        });
        this.xSum = xm;
        this.zSum = zm;
        if (zm > xm) {
            recmV = EnumBjlResult.Z;
            recmMoney = zm - xm;
        }
        else if (xm > zm) {
            recmV = EnumBjlResult.X;
            recmMoney = xm - zm;
        }
        recmInfo.recmV = recmV;
        recmInfo.recmMoney = recmMoney;
        if (recmV != EnumBjlResult.U) {
            recmInfo.betCount++;
        }
        return [recmV, recmMoney];
    }

    showMoney(roundinfo?: RoundInfo): [EnumBjlResult, number] {
        let zm = 0;
        let xm = 0;
        let recmMoney = 0;
        let recmV = EnumBjlResult.U;
        this.subPlan.forEach(pl => {
            if (pl.running) {
                let [rv, rm] = pl.showMoney(roundinfo);
                pl.recmInfo.recmV = rv;
                pl.recmInfo.recmMoney = rm * pl.multiple;
                if (rv == EnumBjlResult.Z) {
                    zm += pl.recmInfo.recmMoney;
                }
                else if (rv == EnumBjlResult.X) {
                    xm += pl.recmInfo.recmMoney;
                }
            }
            else {
                pl.recmInfo.recmV = EnumBjlResult.U;
            }
        });
        if (zm > xm) {
            recmV = EnumBjlResult.Z;
            recmMoney = zm - xm;
        }
        else if (xm > zm) {
            recmV = EnumBjlResult.X;
            recmMoney = xm - zm;
        }

        return [recmV, recmMoney];
    }
    //prevRecm: RecmInfo | null = null;
    resetSummaryInfo: SummaryInfo | null = null;
    resetPlan() {
        if (this.resetSummaryInfo) {
            this.resetSummaryInfo.addSummaryInfo(this.recmInfo.summaryInfo);
        }
        else {
            this.resetSummaryInfo = this.recmInfo.summaryInfo;
        }
        this.recmInfo = new RecmInfo();
        this.userRecmInfo = new RecmInfo();
        this.moneyStrategy.forEach(item => item.resetStrategy());
    }
    resetPlanSummaryInfo() {
        this.recmInfo.summaryInfo.resetSummaryInfo();
        this.recmInfo.roundSummaryInfo.resetSummaryInfo();
        this.userRecmInfo.summaryInfo.resetSummaryInfo();
        this.userRecmInfo.roundSummaryInfo.resetSummaryInfo();
    }
}